package com.sunwayworld.basemodule.rm.material.service.impl;

import com.sunwayworld.basemodule.rm.material.bean.LimsStandardHistoryBean;
import com.sunwayworld.basemodule.rm.material.bean.LimsStandardInventoryBean;
import com.sunwayworld.basemodule.rm.material.dao.LimsStandardInventoryDao;
import com.sunwayworld.basemodule.rm.material.service.LimsStandardHistoryService;
import com.sunwayworld.basemodule.rm.material.service.LimsStandardInventoryService;
import com.sunwayworld.framework.audit.aunnotation.Audit;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.exception.checked.CheckedException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.support.PersistableMetadataHelper;
import com.sunwayworld.framework.utils.ArrayUtils;
import com.sunwayworld.framework.utils.NumberUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.sys.metadata.service.CoreTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.rm.material.dao.LimsMaterialDao;
import com.sunwayworld.basemodule.rm.material.bean.LimsMaterialBean;
import com.sunwayworld.basemodule.rm.material.service.LimsMaterialService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsMaterialServiceImpl implements LimsMaterialService {

    @Autowired
    private LimsMaterialDao limsMaterialDao;

    @Autowired
    private LimsStandardInventoryService limsStandardInventoryService;

    @Autowired
    @Lazy
    private LimsStandardHistoryService limsStandardHistoryService;

    @Override
    @SuppressWarnings("unchecked")
    public LimsMaterialDao getDao() {
        return limsMaterialDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsMaterialBean limsMaterial = jsonWrapper.parseUnique(LimsMaterialBean.class);
        limsMaterial.setId(ApplicationContextHelper.getNextIdentity());
        if (limsMaterial.getMatNum() == null) {
            limsMaterial.setMatNum(0.0);
        }
        if (StringUtils.isBlank(limsMaterial.getMinimum())) {
            limsMaterial.setMinimum("0");
        }
        getDao().insert(limsMaterial);
        return limsMaterial.getId();
    }

    @Transactional
    @AuditTrailEntry(AuditTrailType.DELETE)
    @Audit("AUDIT.DELETE")
    public void delete(RestJsonWrapperBean wrapper) {
        List<LimsMaterialBean> deleteList = wrapper.parse(this.getDao().getType());
        if (!deleteList.isEmpty()) {
            List<Long> idList = deleteList.stream().map(LimsMaterialBean::getId).collect(Collectors.toList());
            deleteList = selectListByIds(idList);

            // 校验材料底下是否存在库存 2022-12-30
            List<String> matCodeList = deleteList.stream().map(LimsMaterialBean::getMatCode).collect(Collectors.toList());
            List<LimsStandardInventoryBean> standardInventoryBeanList = limsStandardInventoryService.selectListByFilter(SearchFilter.instance().match("MATCODE", matCodeList).filter(MatchPattern.OR));
            StringBuffer message = new StringBuffer();
            matCodeList.forEach(mc -> {
                standardInventoryBeanList.stream().filter(sib -> sib.getMatCode().equals(mc)).findAny().ifPresent(sib -> {
                    message.append(mc).append("<br/>");
                });
            });
            if (message.length() > 0) {
                message.append("材料下存在入库数据，请勿删除");
                throw new CheckedException(message.toString());
            }

            List<Long> standardIdList = standardInventoryBeanList.stream().map(LimsStandardInventoryBean::getId).collect(Collectors.toList());
            List<LimsStandardHistoryBean> standardHistoryBeanList = null;
            // 先删除操作记录
            if (!standardIdList.isEmpty()) {
                standardHistoryBeanList = limsStandardHistoryService.selectListByFilter(SearchFilter.instance().match("STANDARDINVENTORYID", standardIdList).filter(MatchPattern.OR), wrapper);
                limsStandardHistoryService.getDao().deleteBy(standardHistoryBeanList, "id");
            }
            // 删除批次记录
            limsStandardInventoryService.getDao().deleteBy(standardInventoryBeanList, "id");

            Class<LimsMaterialBean> itemType = this.getDao().getType();
            CoreTableService tableService = ApplicationContextHelper.getBean(CoreTableService.class);
            deleteList.forEach((t) -> {
                tableService.deleteCascade(PersistableMetadataHelper.getTableName(itemType), (Serializable) t.getId());
            });
        }
    }
}
